import { Injectable, UnauthorizedException } from '@nestjs/common';
import { JwtService } from '@nestjs/jwt';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import { ethers } from 'ethers';
import { User } from '../../users/entities/user.entity';
import { WalletAuthDto } from '../dto/wallet-auth.dto';
import { ConfigService } from '@nestjs/config';
import { AppI18nService } from '../../i18n/i18n.service';

@Injectable()
export class WalletAuthService {
    constructor(
        @InjectRepository(User)
        private userRepository: Repository<User>,
        private jwtService: JwtService,
        private configService: ConfigService,
        private i18nService: AppI18nService,
    ) { }

    async walletLogin(walletAuthDto: WalletAuthDto, language = 'en') {
        let { walletAddress, message, signature, chainId } = walletAuthDto;

        walletAddress = ethers.getAddress(walletAddress);

        // 验证签名
        const isValidSignature = this.verifySignature(message, signature, walletAddress);
        if (!isValidSignature) {
            const errorMessage = this.i18nService.getAuthMessage('invalid_signature', {}, language);
            throw new UnauthorizedException(errorMessage);
        }

        // 使用 walletAddress + chainId 作为唯一标识查找或创建用户
        let user = await this.userRepository.findOne({
            where: {
                walletAddress,
                chainId
            }
        });

        if (!user) {
            // 创建新用户
            user = this.userRepository.create({
                walletAddress,
                chainId,
                fullName: walletAuthDto.fullName,
            });
            await this.userRepository.save(user);
        }

        // 生成JWT token，包含 chainId
        const uniqueUserId = `${user.walletAddress}${user.chainId}`;
        const payload = {
            walletAddress: user.walletAddress,
            chainId: user.chainId,
            sub: uniqueUserId
        };

        const token = this.jwtService.sign(payload, {
            secret: this.configService.get('jwt.secret'),
            expiresIn: this.configService.get('jwt.expiresIn'),
        });

        return {
            access_token: token,
            user: {
                walletAddress: user.walletAddress,
                chainId: user.chainId,
                fullName: user.fullName,
            },
        };
    }

    private verifySignature(message: string, signature: string, walletAddress: string): boolean {
        try {
            const recoveredAddress = ethers.verifyMessage(message, signature);
            return recoveredAddress.toLowerCase() === walletAddress.toLowerCase();
        } catch (error) {
            return false;
        }
    }
}
